﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;
using HYElectricKernel;
using TopologySearch;

namespace HYRElectric.WirePlace
{
	internal class EquipmentEdgeLine
	{
		public EquipmentEdgeLine(Document doc)
		{
			this.doc = doc;
		}

		public EquipmentEdgeLine(Document doc, Element startDevice, Element endDevice, WireParams wireParams)
		{
			this.doc = doc;
			this.startDevice = startDevice;
			this.endDevice = endDevice;
			this.wiringType = wireParams.WireStyle;
		}

		public void GetDeviceEdgePoints(ref EdgeInfo edge, XYZ wireCenter = null)
		{
			Connector deviceConnector = RevitUtils.GetDeviceConnector(this.startDevice);
			Connector deviceConnector2 = RevitUtils.GetDeviceConnector(this.endDevice);
			try
			{
				YJKLine YJKLine = new YJKLine(YJKRevitTools.SetZToZero(deviceConnector.Origin), YJKRevitTools.SetZToZero(deviceConnector2.Origin));
				YJKLine.MakeUnBound();
				List<Curve> deviceEdgeCurves = this.GetDeviceEdgeCurves(this.startDevice);
				this.MirroredCurves(this.startDevice, ref deviceEdgeCurves);
				List<Curve> list = new List<Curve>();
				List<Curve> list2 = new List<Curve>();
				this.SplitCurves(deviceEdgeCurves, list, list2);
				List<XYZ> list3 = new List<XYZ>();
				XYZ aimPoint = new XYZ(deviceConnector.Origin.X, deviceConnector.Origin.Y, 0.0);
				BoundingBoxUV boundingBoxUV = new BoundingBoxUV();
				if (list2.Count > 0)
				{
					list3 = this.getJoinPoint(list2, true, YJKLine);
					boundingBoxUV = this.GetBoundingBox(list2);
				}
				else
				{
					list3 = this.getNoBoundCurvePoint(list);
					boundingBoxUV = this.GetBoundingBox(list);
				}
				if (boundingBoxUV != null)
				{
					UV uv = (boundingBoxUV.Min + boundingBoxUV.Max) / 2.0;
					aimPoint = new XYZ(uv.U, uv.V, 0.0);
				}
				List<Curve> deviceEdgeCurves2 = this.GetDeviceEdgeCurves(this.endDevice);
				this.MirroredCurves(this.endDevice, ref deviceEdgeCurves2);
				List<Curve> list4 = new List<Curve>();
				List<Curve> list5 = new List<Curve>();
				this.SplitCurves(deviceEdgeCurves2, list4, list5);
				List<XYZ> list6 = new List<XYZ>();
				XYZ aimPoint2 = new XYZ(deviceConnector2.Origin.X, deviceConnector2.Origin.Y, 0.0);
				BoundingBoxUV boundingBoxUV2 = new BoundingBoxUV();
				if (list5.Count > 0)
				{
					list6 = this.getJoinPoint(list5, true, YJKLine);
					boundingBoxUV2 = this.GetBoundingBox(list5);
				}
				else
				{
					list6 = this.getNoBoundCurvePoint(list4);
					boundingBoxUV2 = this.GetBoundingBox(list4);
				}
				if (boundingBoxUV2 != null)
				{
					UV uv2 = (boundingBoxUV2.Min + boundingBoxUV2.Max) / 2.0;
					aimPoint2 = new XYZ(uv2.U, uv2.V, 0.0);
				}
				XYZ xyz;
				if (list3.Count > 0)
				{
					xyz = this.GetClosePoint(list3, aimPoint2);
				}
				else
				{
					xyz = deviceConnector.Origin;
				}
				XYZ xyz2;
				if (list6.Count > 0)
				{
					xyz2 = this.GetClosePoint(list6, aimPoint);
				}
				else
				{
					xyz2 = deviceConnector2.Origin;
				}
                if (this.wiringType == (WiringType)0)
				{
					Curve curve;
					if (wireCenter != null)
					{
						curve = NewConnectWire.GetArcByCenter(this.doc, xyz, xyz2, wireCenter);
					}
					else
					{
						curve = NewConnectWire.GetArc(this.doc, xyz, xyz2, true);
					}
					XYZ center = (curve as Arc).Center;
					XYZ normal = (curve as Arc).Normal;
					bool isAnticlockwise = false;
					if (normal.IsAlmostEqualTo(XYZ.BasisZ))
					{
						isAnticlockwise = true;
					}
					double bulge = Geometry.GetBulge(xyz, xyz2, center, isAnticlockwise);
					edge = new EdgeInfo(xyz, xyz2, bulge);
				}
				else
				{
					edge = new EdgeInfo(xyz, xyz2, 0.0);
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
				XYZ xyz = deviceConnector.Origin;
				XYZ xyz2 = deviceConnector2.Origin;
				edge = new EdgeInfo(xyz, xyz2, 0.0);
			}
		}

		private XYZ GetClosePoint(List<XYZ> points, XYZ aimPoint)
		{
			XYZ xyz = points[0];
			double num = aimPoint.DistanceTo(xyz);
			for (int i = 1; i < points.Count; i++)
			{
				double num2 = aimPoint.DistanceTo(points[i]);
				if (num > num2)
				{
					xyz = points[i];
					num = num2;
				}
			}
			return xyz;
		}

		public List<Curve> MirroredCurves(Element device, ref List<Curve> deviceCurves)
		{
			List<Curve> list = new List<Curve>();
			FamilyInstance familyInstance = device as FamilyInstance;
			if (familyInstance.Mirrored)
			{
				Transform transform = Transform.CreateReflection(RevitVersionFuncs.CreatePlanByNormalAndOrigin(familyInstance.FacingOrientation, (familyInstance.Location as LocationPoint).Point));
				foreach (Curve curve in deviceCurves)
				{
					list.Add(curve.CreateTransformed(transform));
				}
			}
			if (list.Count > 0)
			{
				deviceCurves = list;
			}
			return deviceCurves;
		}

		private BoundingBoxUV GetBoundingBox(List<Curve> curves)
		{
			if (curves.Count == 0)
			{
				return null;
			}
			BoundingBoxUV boundingBoxUV = this.GetBoundingBox(curves[0]);
			for (int i = 1; i < curves.Count; i++)
			{
				BoundingBoxUV boundingBox = this.GetBoundingBox(curves[i]);
				boundingBoxUV = Geometry.BoundingBoxesMerge(boundingBoxUV, boundingBox);
			}
			return boundingBoxUV;
		}

		private BoundingBoxUV GetBoundingBox(Curve curve)
		{
			if (curve.GetType() == typeof(Line))
			{
				return Geometry.CalculateBoundingBox2D(curve as Line);
			}
			if (!(curve.GetType() == typeof(Arc)))
			{
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				return Geometry.CalculateBoundingBox2D(hyendPoint, hyendPoint2);
			}
			if (!curve.IsBound)
			{
				Arc arc = curve as Arc;
				double radius = arc.Radius;
				XYZ center = arc.Center;
				XYZ xyz = center + XYZ.BasisX * radius;
				XYZ xyz2 = center + -XYZ.BasisX * radius;
				XYZ xyz3 = center + XYZ.BasisY * radius;
				XYZ xyz4 = center + -XYZ.BasisY * radius;
				return new BoundingBoxUV(xyz2.X, xyz4.Y, xyz.X, xyz3.Y);
			}
			return Geometry.CalculateBoundingBox2D(curve as Arc);
		}

		private List<XYZ> getJoinPoint(List<Curve> lCurves, bool isBoundArea, YJKLine hyBaseLine)
		{
			List<Curve> list = this.MergeCurves(lCurves);
			bool flag = false;
			if (3 == list.Count)
			{
				flag = true;
			}
			List<XYZ> list2 = new List<XYZ>();
			foreach (Curve curve in list)
			{
				IList<XYZ> list3 = curve.Tessellate();
				if (list3.Count == 2)
				{
					XYZ hyendPoint = curve.GetEndPoint(0);
					XYZ hyendPoint2 = curve.GetEndPoint(1);
					XYZ ptmid = (hyendPoint + hyendPoint2) / 2.0;
					if (!list2.Exists((XYZ pt) => pt.IsAlmostEqualTo(ptmid)))
					{
						list2.Add(ptmid);
					}
					if (flag)
					{
						list2.Add(hyendPoint);
						list2.Add(hyendPoint2);
					}
				}
				else
				{
					if (curve is Arc || curve.IsCyclic)
					{
						YJKCurve hycurve = new YJKCurve(curve);
						double z = list3.First<XYZ>().Z;
						hyBaseLine = new YJKLine(new XYZ(hyBaseLine.StartPoint.X, hyBaseLine.StartPoint.Y, z), new XYZ(hyBaseLine.EndPoint.X, hyBaseLine.EndPoint.Y, z));
						List<XYZ> list4 = hycurve.IntersectionAllPoint(hyBaseLine.Line);
						if (list4 != null && list4.Count > 0)
						{
							list2.AddRange(list4);
							continue;
						}
					}
					if (curve.IsBound)
					{
						XYZ xyz = list3.First<XYZ>();
						XYZ xyz2 = list3.Last<XYZ>();
						XYZ item = (xyz + xyz2) / 2.0;
						XYZ xyz3 = hyBaseLine.IntersectionPoint(new YJKLine(YJKRevitTools.SetZToZero(xyz), YJKRevitTools.SetZToZero(xyz2)).Line);
						if (xyz3 != null)
						{
							item = xyz3;
						}
						list2.Add(item);
						if (flag)
						{
							list2.Add(xyz);
							list2.Add(xyz2);
						}
					}
					IEnumerator<XYZ> enumerator2 = list3.GetEnumerator();
					{
						while (enumerator2.MoveNext())
						{
							XYZ pttmp = enumerator2.Current;
							if (!list2.Exists((XYZ pt) => pt.IsAlmostEqualTo(pttmp)))
							{
								list2.Add(pttmp);
							}
						}
					}
				}
			}
			return list2;
		}

		private List<XYZ> getNoBoundCurvePoint(List<Curve> iCurves)
		{
			List<Curve> list = this.MergeCurves(iCurves);
			List<Curve> list2 = new List<Curve>();
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].Tessellate().Count > 2)
				{
					list2.Add(list[i]);
					list.RemoveAt(i);
					i--;
				}
			}
			List<XYZ> result = new List<XYZ>();
			if (list2.Count > 0)
			{
				result = this.DisposeCurveForPoints(list2, list);
			}
			else
			{
				result = this.DisposeLineForPoints(list);
			}
			return result;
		}

		private List<XYZ> DisposeLineForPoints(List<Curve> iLines)
		{
			new List<XYZ>();
			Dictionary<XYZ, int> relationLAndP = this.getRelationLAndP(iLines);
			List<Dictionary<int, int>> templates = this.setSpecialTemplate();
			return this.MatchTmpAndGetJoinPts(relationLAndP, templates);
		}

		private List<XYZ> MatchTmpAndGetJoinPts(Dictionary<XYZ, int> relations, List<Dictionary<int, int>> templates)
		{
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			foreach (KeyValuePair<XYZ, int> keyValuePair in relations)
			{
				int value = keyValuePair.Value;
				if (dictionary.ContainsKey(value))
				{
					int num = dictionary[value];
					dictionary[value] = num + 1;
				}
				else
				{
					dictionary.Add(value, 1);
				}
			}
			dictionary = (from v in dictionary
			orderby v.Key
			select v).ToDictionary((KeyValuePair<int, int> v) => v.Key, (KeyValuePair<int, int> p) => p.Value);
			int num2 = 0;
			for (int i = 0; i < templates.Count; i++)
			{
				Dictionary<int, int> dictionary2 = templates[i];
				if (dictionary2.Count == dictionary.Count)
				{
					List<int> list = new List<int>(dictionary2.Keys);
					List<int> list2 = new List<int>(dictionary.Keys);
					int num3 = 0;
					while (num3 < list.Count && list[num3].Equals(list2[num3]) && dictionary2[list[num3]].Equals(dictionary[list2[num3]]))
					{
						num3++;
					}
					if (num3 == list.Count)
					{
						num2 = i + 1;
						break;
					}
				}
			}
			List<XYZ> list3 = new List<XYZ>();
			if (num2 != 0)
			{
				list3 = this.GetTemplatePoints(num2, relations);
			}
			else
			{
				foreach (KeyValuePair<XYZ, int> keyValuePair2 in relations)
				{
					if (keyValuePair2.Value == 3)
					{
						list3.Add(keyValuePair2.Key);
					}
				}
			}
			return list3;
		}

		private List<Dictionary<int, int>> setSpecialTemplate()
		{
			return new List<Dictionary<int, int>>
			{
				new Dictionary<int, int>
				{
					{
						1,
						4
					},
					{
						3,
						2
					}
				},
				new Dictionary<int, int>
				{
					{
						1,
						3
					},
					{
						2,
						2
					},
					{
						3,
						1
					}
				}
			};
		}

		private List<XYZ> GetTemplatePoints(int nIndex, Dictionary<XYZ, int> relations)
		{
			List<XYZ> result = new List<XYZ>();
			if (nIndex != 1)
			{
				if (nIndex == 2)
				{
					result = this.GetTemplateTwo(relations);
				}
			}
			else
			{
				result = this.GetTemplateOne(relations);
			}
			return result;
		}

		private List<XYZ> GetTemplateOne(Dictionary<XYZ, int> relations)
		{
			List<XYZ> list = new List<XYZ>();
			List<XYZ> list2 = new List<XYZ>();
			foreach (KeyValuePair<XYZ, int> keyValuePair in relations)
			{
				if (keyValuePair.Value == 3)
				{
					list2.Add(keyValuePair.Key);
					list.Add(keyValuePair.Key);
				}
			}
			if (2 == list2.Count)
			{
				XYZ item = (list2[0] + list2[1]) / 2.0;
				list.Add(item);
			}
			return list;
		}

		private List<XYZ> GetTemplateTwo(Dictionary<XYZ, int> relations)
		{
			List<XYZ> list = new List<XYZ>();
			List<XYZ> list2 = new List<XYZ>();
			List<XYZ> list3 = new List<XYZ>();
			foreach (KeyValuePair<XYZ, int> keyValuePair in relations)
			{
				if (keyValuePair.Value == 1)
				{
					list2.Add(keyValuePair.Key);
				}
				else if (2 == keyValuePair.Value)
				{
					list3.Add(keyValuePair.Key);
				}
			}
			if (2 == list3.Count && 3 == list2.Count)
			{
				XYZ xyz = list3[1] - list3[0];
				new XYZ();
				XYZ xyz2 = (list3[1] + list3[0]) / 2.0;
				XYZ xyz3 = new XYZ();
				if (xyz.IsAlmostEqualTo(list2[1] - list2[0]) || xyz.IsAlmostEqualTo(list2[0] - list2[1]))
				{
					xyz3 = (list2[1] + list2[0]) / 2.0;
					list.Add(list2[2]);
				}
				else if (xyz.IsAlmostEqualTo(list2[2] - list2[0]) || xyz.IsAlmostEqualTo(list2[0] - list2[2]))
				{
					xyz3 = (list2[2] + list2[0]) / 2.0;
					list.Add(list2[1]);
				}
				else
				{
					xyz3 = (list2[2] + list2[1]) / 2.0;
					list.Add(list2[0]);
				}
				list.Add(list3[0] + (xyz3 - xyz2) / 2.0);
				list.Add(list3[1] + (xyz3 - xyz2) / 2.0);
				list.Add(xyz3 + (xyz3 - xyz2) / 2.0);
			}
			return list;
		}

		private Dictionary<XYZ, int> getRelationLAndP(List<Curve> iLines)
		{
			Dictionary<XYZ, int> dictionary = new Dictionary<XYZ, int>();
			for (int i = 0; i < iLines.Count; i++)
			{
				Curve curve = iLines[i];
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				this.AddOrModifyRelations(hyendPoint, 1, dictionary);
				this.AddOrModifyRelations(hyendPoint2, 1, dictionary);
				for (int j = i + 1; j < iLines.Count; j++)
				{
					Curve curve2 = iLines[j];
					new IntersectionResultArray();
					IntersectionResultArray intersectionResultArray;
					if (curve.Intersect(curve2, out intersectionResultArray) == SetComparisonResult.Overlap)
					{
						XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
						if ((!hyendPoint.IsAlmostEqualTo(xyzpoint) && !hyendPoint2.IsAlmostEqualTo(xyzpoint)) || (!curve2.GetEndPoint(0).IsAlmostEqualTo(xyzpoint) && !curve2.GetEndPoint(1).IsAlmostEqualTo(xyzpoint)))
						{
							this.AddOrModifyRelations(xyzpoint, 2, dictionary);
						}
					}
				}
				iLines.RemoveAt(i);
				i--;
			}
			return dictionary;
		}

		private void AddOrModifyRelations(XYZ iPt, int inCount, Dictionary<XYZ, int> ioRelations)
		{
			bool flag = false;
			foreach (KeyValuePair<XYZ, int> keyValuePair in ioRelations)
			{
				if (iPt.IsAlmostEqualTo(keyValuePair.Key))
				{
					int num = keyValuePair.Value;
					num += inCount;
					ioRelations[keyValuePair.Key] = num;
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				ioRelations.Add(iPt, inCount);
			}
		}

		private List<XYZ> DisposeCurveForPoints(List<Curve> iCurves, List<Curve> iLine)
		{
			List<XYZ> list = new List<XYZ>();
			List<XYZ> list2 = new List<XYZ>();
			List<XYZ> list3 = new List<XYZ>();
			foreach (Curve curve in iCurves)
			{
				XYZ xyz = curve.GetEndPoint(0);
				XYZ xyz2 = curve.GetEndPoint(1);
				XYZ xyz3 = (xyz + xyz2) / 2.0;
				list3.Add(xyz);
				list3.Add(xyz2);
				list2.Add((xyz2 - xyz).Normalize());
				Arc arc = (Arc)curve;
				XYZ xyz4 = AxisAssistFunc.CalculatMidPoint(xyz, xyz2, arc.Center, arc.Normal);
				double num = xyz4.DistanceTo(xyz3) / 2.0;
				XYZ xyz5 = xyz4 - xyz3;
				xyz += xyz5 * num;
				xyz2 += xyz5 * num;
				xyz3 += (xyz3 - xyz4) * num * 3.0 / 2.0;
				list.Add(xyz3);
				Curve curve2 = Line.CreateBound(xyz, xyz2);
				new IntersectionResultArray();
				IntersectionResultArray intersectionResultArray;
				if (curve2.Intersect(arc, out intersectionResultArray) == SetComparisonResult.Overlap)
				{
					foreach (object obj in intersectionResultArray)
					{
						IntersectionResult intersectionResult = (IntersectionResult)obj;
						IntersectionResult intersectionResult2 = intersectionResult;
						XYZ intersectionPoint = intersectionResult2.XYZPoint;
						if (!list.Exists((XYZ pt) => pt.IsAlmostEqualTo(intersectionPoint)))
						{
							list.Add(intersectionPoint);
						}
					}
				}
			}
			this.DeleteLineByPoints(list3, iLine);
			foreach (Curve curve3 in iLine)
			{
				XYZ hyendPoint = curve3.GetEndPoint(0);
				XYZ hyendPoint2 = curve3.GetEndPoint(1);
				XYZ xyz6 = (hyendPoint2 - hyendPoint).Normalize();
				foreach (XYZ xyz7 in list2)
				{
					XYZ xyz8 = xyz7.CrossProduct(new XYZ(0.0, 0.0, 1.0));
					if (xyz6.IsAlmostEqualTo(xyz7) || xyz6.IsAlmostEqualTo(-xyz7) || xyz6.IsAlmostEqualTo(xyz8) || xyz6.IsAlmostEqualTo(-xyz8))
					{
						list.Add(hyendPoint);
						list.Add(hyendPoint2);
						break;
					}
				}
			}
			return list;
		}

		private void DeleteLineByPoints(List<XYZ> ipts, List<Curve> iLines)
		{
			bool flag = false;
			for (int i = 0; i < ipts.Count; i++)
			{
				XYZ xyz = ipts[i];
				for (int j = 0; j < iLines.Count; j++)
				{
					XYZ hyendPoint = iLines[j].GetEndPoint(0);
					XYZ hyendPoint2 = iLines[j].GetEndPoint(1);
					if (xyz.IsAlmostEqualTo(hyendPoint))
					{
						ipts.Add(hyendPoint2);
						iLines.RemoveAt(j);
						flag = true;
						j--;
					}
					if (xyz.IsAlmostEqualTo(hyendPoint2))
					{
						ipts.Add(hyendPoint);
						iLines.RemoveAt(j);
						flag = true;
						j--;
					}
				}
			}
			if (flag)
			{
				this.DeleteLineByPoints(ipts, iLines);
			}
		}

		private List<Curve> MergeCurves(List<Curve> lCurves)
		{
			List<Curve> list = new List<Curve>();
			for (int i = 0; i < lCurves.Count; i++)
			{
				Curve curve = lCurves[i];
				XYZ xyz = new XYZ();
				IList<XYZ> list2 = curve.Tessellate();
				if (list2.Count == 2)
				{
					xyz = curve.GetEndPoint(0) - curve.GetEndPoint(1);
					bool flag = false;
					for (int j = 0; j < lCurves.Count; j++)
					{
						Curve curve2 = lCurves[j];
						if (!(curve == curve2))
						{
							XYZ xyz2 = new XYZ();
							IList<XYZ> list3 = curve2.Tessellate();
							if (list3.Count == 2)
							{
								xyz2 = curve2.GetEndPoint(0) - curve2.GetEndPoint(1);
								double num = xyz.AngleTo(xyz2);
								if (Math.Abs(num - Math.PI) < 0.0001 || num < 0.0001)
								{
									new IntersectionResultArray();
									IntersectionResultArray intersectionResultArray;
                                    if (curve.Intersect(curve2, out intersectionResultArray) == (SetComparisonResult)16)
									{
										XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
										XYZ xyz3 = new XYZ();
										XYZ xyz4 = new XYZ();
										if (xyzpoint.IsAlmostEqualTo(list2[0]))
										{
											xyz3 = list2[1];
										}
										else
										{
											xyz3 = list2[0];
										}
										if (xyzpoint.IsAlmostEqualTo(list3[0]))
										{
											xyz4 = list3[1];
										}
										else
										{
											xyz4 = list3[0];
										}
										Line line = Line.CreateBound(xyz3, xyz4);
										int num2 = 0;
										while (num2 < list.Count && !list[num2].Equals(line))
										{
											num2++;
										}
										if (num2 == list.Count)
										{
											list.Add(line);
										}
										lCurves.RemoveAt(j);
										j--;
										lCurves.RemoveAt(i);
										i--;
										lCurves.Add(line);
										flag = true;
										break;
									}
								}
							}
							else
							{
								list.Add(curve2);
								lCurves.RemoveAt(j);
								j--;
							}
						}
					}
					if (!flag)
					{
						int num3 = 0;
						while (num3 < list.Count && !list[num3].Equals(curve))
						{
							num3++;
						}
						if (num3 == list.Count)
						{
							list.Add(curve);
						}
						lCurves.RemoveAt(i);
						i--;
					}
				}
				else
				{
					list.Add(curve);
					lCurves.RemoveAt(i);
					i--;
				}
			}
			return list;
		}

		private void SplitCurves(List<Curve> allCurves, List<Curve> lines, List<Curve> boundCurves)
		{
			List<Curve> list = new List<Curve>();
			List<Curve> list2 = new List<Curve>();
			double num = 0.0;
			foreach (Curve curve in allCurves)
			{
				if (curve.Tessellate().Count == 2)
				{
					list.Add(curve);
				}
				else
				{
					Arc arc = curve as Arc;
					if (!(null == arc))
					{
						if (arc.IsBound)
						{
							lines.Add(curve);
						}
						else if (arc.Length > num)
						{
							num = arc.Length;
							boundCurves.Clear();
							boundCurves.Add(curve);
						}
					}
				}
			}
			List<Curve> list3 = new List<Curve>();
			if (lines != null && lines.Count > 0)
			{
				foreach (Curve curve2 in lines)
				{
					YJKCurve hycurve = new YJKCurve(curve2);
					IList<XYZ> list4 = curve2.Tessellate();
					double z = list4.First<XYZ>().Z;
					bool flag = false;
					foreach (Curve curve3 in allCurves)
					{
						Line line = curve3 as Line;
						if (!(line == null))
						{
							YJKLine YJKLine = new YJKLine(line);
							YJKLine = new YJKLine(new XYZ(YJKLine.StartPoint.X, YJKLine.StartPoint.Y, z), new XYZ(YJKLine.EndPoint.X, YJKLine.EndPoint.Y, z));
							list4 = hycurve.IntersectionAllPoint(YJKLine.Line);
							if (list4 != null && list4.Count > 1)
							{
								list3.Add(curve3);
								flag = true;
							}
						}
					}
					if (flag)
					{
						list3.Add(curve2);
					}
				}
			}
			this.findBoundAreaLines(list, lines, list2);
			if (list3.Count > 0)
			{
				list2.AddRange(list3);
			}
			if (list2.Count > 1)
			{
				List<Pole2D> list5 = new List<Pole2D>();
				foreach (Curve curve4 in list2)
				{
					Pole2D item = Pole2D.TransformWallToStructure2DPole(curve4, ElementId.InvalidElementId, 0.0, 0.0);
					list5.Add(item);
				}
				List<List<Curve>> fullFloorEdgeLoops = new StructureLoopSearcher(this.doc).GetFullFloorEdgeLoops(list5, StructureLoopSearcher.SearchEdgeLocation.SEL_Outside);
				double num2 = 0.0;
				int num3 = -1;
				for (int i = 0; i < fullFloorEdgeLoops.Count; i++)
				{
					double num4 = 0.0;
					foreach (Curve curve5 in fullFloorEdgeLoops[i])
					{
						num4 += curve5.Length;
					}
					if (i == 0 || (i != 0 && num2 < num4))
					{
						num2 = num4;
						num3 = i;
					}
				}
				if (-1 != num3 && num2 > num)
				{
					boundCurves.Clear();
					foreach (Curve item2 in fullFloorEdgeLoops[num3])
					{
						boundCurves.Add(item2);
					}
				}
			}
		}

		private void findBoundAreaLines(List<Curve> allCurves, List<Curve> lines, List<Curve> boundCurves)
		{
			bool flag = false;
			for (int i = 0; i < allCurves.Count; i++)
			{
				int num = 0;
				List<XYZ> list = new List<XYZ>();
				Curve curve = allCurves[i];
				foreach (Curve curve2 in allCurves)
				{
					if (!(curve == curve2))
					{
						new IntersectionResultArray();
						IntersectionResultArray intersectionResultArray;
						if (curve2.Intersect(curve, out intersectionResultArray) == SetComparisonResult.Overlap)
						{
							foreach (object obj in intersectionResultArray)
							{
								IntersectionResult intersectionResult = (IntersectionResult)obj;
								num++;
								IntersectionResult intersectionResult2 = intersectionResult;
								XYZ intersectionPoint = intersectionResult2.XYZPoint;
								if (!list.Exists((XYZ pt) => pt.IsAlmostEqualTo(intersectionPoint)))
								{
									list.Add(intersectionPoint);
								}
							}
						}
					}
				}
				if (num < 2 || list.Count < 2)
				{
					lines.Add(curve);
					allCurves.Remove(curve);
					i--;
					flag = true;
				}
			}
			if (flag)
			{
				this.findBoundAreaLines(allCurves, lines, boundCurves);
				return;
			}
			if (allCurves.Count < 3)
			{
				using (List<Curve>.Enumerator enumerator = allCurves.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						Curve item = enumerator.Current;
						lines.Add(item);
					}
					return;
				}
			}
			foreach (Curve item2 in allCurves)
			{
				boundCurves.Add(item2);
			}
		}

		private void GetArcAndLine(List<Curve> allCurves, ref Curve arc, ref Curve line)
		{
			arc = null;
			line = null;
			if (allCurves == null || allCurves.Count != 2)
			{
				return;
			}
			if (allCurves.First<Curve>() is Arc && allCurves.Last<Curve>() is Line)
			{
				if (this.CheckArcLineBeBound(allCurves.First<Curve>() as Arc, allCurves.Last<Curve>() as Line))
				{
					arc = allCurves.First<Curve>();
					line = allCurves.Last<Curve>();
					return;
				}
			}
			else if (allCurves.Last<Curve>() is Arc && allCurves.First<Curve>() is Line && this.CheckArcLineBeBound(allCurves.Last<Curve>() as Arc, allCurves.First<Curve>() as Line))
			{
				arc = allCurves.Last<Curve>();
				line = allCurves.First<Curve>();
			}
		}

		private bool CheckArcLineBeBound(Curve arc, Line line)
		{
			IEnumerable<XYZ> source = arc.Tessellate();
			YJKCurve hycurve = new YJKCurve(arc);
			double z = source.First<XYZ>().Z;
			YJKLine YJKLine = new YJKLine(line);
			YJKLine = new YJKLine(new XYZ(YJKLine.StartPoint.X, YJKLine.StartPoint.Y, z), new XYZ(YJKLine.EndPoint.X, YJKLine.EndPoint.Y, z));
			List<XYZ> list = hycurve.IntersectionAllPoint(YJKLine.Line);
			return list != null && list.Count == 2;
		}

		public List<Curve> GetDeviceEdgeCurves(Element element)
		{
			return this.GetDeviceCurves(element);
		}

		private List<Curve> GetDeviceCurves(Element element)
		{
			List<Curve> list = new List<Curve>();
			this.GetFamilyElements(element, list);
			return list;
		}

		private void GetFamilyElements(Element element, List<Curve> allCurves)
		{
			Instance instance = element as Instance;
			Transform transform = instance.GetTransform();
			Family family = (element as FamilyInstance).Symbol.Family;
			Document document = this.doc.EditFamily(family);
			if (document == null || !document.IsFamilyDocument)
			{
				TaskDialog.Show("盈建科提示", "it's family document");
				return;
			}
			IEnumerable<Element> enumerable = new FilteredElementCollector(document).OfClass(typeof(FamilyInstance)).ToElements();
			List<Element> list = new List<Element>();
			foreach (Element element2 in enumerable)
			{
				if (element2 is AnnotationSymbol || element2.Category.Id.IntegerValue == -2002000)
				{
					if (RevitVersionFuncs.GetFamilyCategory((element2 as FamilyInstance).Symbol.Family).Id.IntegerValue.ToString() == "OST_GenericAnnotation" || element2.Category.Id.IntegerValue == -2002000)
					{
						list.Add(element2);
						break;
					}
				}
				else if (element2.Category.Id == element.Category.Id && (element2 as FamilyInstance).Symbol.Family.Name.Contains("图例"))
				{
					list.Add(element2);
				}
			}
			if (list.Count < 1)
			{
				return;
			}
			Element element3 = list[0];
			if (list.Count > 1)
			{
				string text = "固定尺寸图例";
				Parameter parameter = instance.GetParameter(text);
				if (parameter != null)
				{
					if ("是" != parameter.AsValueString())
					{
						text = "实际尺寸图例";
					}
					foreach (Element element4 in list)
					{
						if ((element4 as FamilyInstance).Symbol.Family.Name.Contains(text))
						{
							element3 = element4;
							break;
						}
					}
				}
			}
			Transform transform2 = (element3 as Instance).GetTransform();
			Family family2 = (element3 as FamilyInstance).Symbol.Family;
			this.GetSubFamilyElements(family2, transform, transform2, allCurves);
		}

		private void GetSubFamilyElements(Family family, Transform ts, Transform tsForm, List<Curve> allCurves)
		{
			Document document = null;
			try
			{
				document = this.doc.EditFamily(family);
			}
			catch (Exception)
			{
				return;
			}
			int scale = this.doc.ActiveView.Scale;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
			filteredElementCollector.OfClass(typeof(CurveElement));
			foreach (Element element in filteredElementCollector.ToElements())
			{
				if (element is DetailCurve || element is ModelCurve)
				{
					int integerValue = element.Category.Id.IntegerValue;
					element.Category.Id.IntegerValue.ToString();
					if (element.Category.Id.IntegerValue.ToString() == "OST_Lines")
					{
						int num = element.get_Parameter(BuiltInParameter.GEOM_VISIBILITY_PARAM).AsInteger();
						if (this.IsCoarse(num) && num != -1)
						{
							Curve curve = (element.Location as LocationCurve).Curve;
							Curve curve2;
							if (RevitVersionFuncs.GetFamilyCategory(family).Id.IntegerValue == -2000150)
							{
								Transform transform = Transform.Identity;
								double num2 = (double)scale;
								transform = transform.ScaleBasis(num2);
								curve2 = curve.CreateTransformed(transform);
							}
							else
							{
								curve2 = curve;
							}
							Curve item = curve2.CreateTransformed(tsForm).CreateTransformed(ts);
							allCurves.Add(item);
						}
					}
				}
			}
		}

		private bool IsCoarse(int value)
		{
			return (value & 8254) != 0;
		}

		public XYZ TransformPoint(XYZ point, Transform transform)
		{
			double x = point.X;
			double y = point.Y;
			double z = point.Z;
			XYZ xyz = transform.get_Basis(0);
			XYZ xyz2 = transform.get_Basis(1);
			XYZ xyz3 = transform.get_Basis(2);
			XYZ origin = transform.Origin;
			double num = x * xyz.X + y * xyz2.X + z * xyz3.X + origin.X;
			double num2 = x * xyz.Y + y * xyz2.Y + z * xyz3.Y + origin.Y;
			double num3 = x * xyz.Z + y * xyz2.Z + z * xyz3.Z + origin.Z;
			return new XYZ(num, num2, num3);
		}

		private Document doc;

		private Element startDevice;

		private Element endDevice;

		private WiringType wiringType;

		private XYZ deviceLocation;

		private List<LineEndPoint> lineEndPoints = new List<LineEndPoint>();

		private List<ArcEndPoint> ArcEndPoints = new List<ArcEndPoint>();
	}
}
